package cn.wolfcode.p2p.base.service.impl;
import cn.wolfcode.p2p.Exception.ErrorCode;
import cn.wolfcode.p2p.base.domain.Account;
import cn.wolfcode.p2p.base.domain.LoginInfo;
import cn.wolfcode.p2p.base.domain.UserInfo;
import cn.wolfcode.p2p.base.mapper.LoginInfoMapper;
import cn.wolfcode.p2p.base.service.IAccountService;
import cn.wolfcode.p2p.base.service.ILoginInfoService;
import cn.wolfcode.p2p.base.service.IUserInfoService;
import cn.wolfcode.p2p.business.domain.ExpAccount;
import cn.wolfcode.p2p.business.service.ICallInterfaceService;
import cn.wolfcode.p2p.business.service.IExpAccountGrantRecordService;
import cn.wolfcode.p2p.business.service.IExpAccountService;
import cn.wolfcode.p2p.util.*;
import cn.wolfcode.p2p.vo.UserInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class LoginInfoServiceImpl implements ILoginInfoService,ApplicationListener<ContextRefreshedEvent> {
    @Autowired
    private LoginInfoMapper loginInfoMapper;

    @Autowired
    private IAccountService accountService;

    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private ICallInterfaceService callInterfaceService;

    @Autowired
    private IExpAccountService expaccountService;

    @Autowired
    private IExpAccountGrantRecordService expAccountGrantRecordService;

    @Override
    public int insert(LoginInfo record) {
        return loginInfoMapper.insert(record);
    }


    @Override
    public void register(String username, String verifycode, String password ,String confirmPwd) {
        AssertUtil.instance()
                .isMobile(username,ErrorCode.USERNAME_FORMAT_ERROR)
                .isFalse(existUsername(username),ErrorCode.USERNAME_IS_EXIST)
                .isNotNull(password,ErrorCode.PASSWORD_ISNULL)
                .isLength(password.length(),Constant.PASSWORD_MIN_LENGTH,Constant.PASSWORD_MAX_LENGTH,ErrorCode.PASSWORD_LENGTH_ERROR)
                .isNotNull(confirmPwd,ErrorCode.CONFIRMPWD_ISNULL)
                .isEquals(password,confirmPwd,ErrorCode.PASSWORD_MISMATCHING)
                .isNotNull(verifycode,ErrorCode.VERIFYCODE_ISNULL)
                .isLength(verifycode.length(),Constant.VERIFYCODE_LENGTH,ErrorCode.VERIFYCODE_LENGTH_ERROR);
        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setUsername(username);
        loginInfo.setPassword(MD5.encode(password + username));
        loginInfo.setState(0);


        UserInfoVo userInfoVo = UserContext.getUserInfoVo();
        if (userInfoVo != null) {
            Date date = new Date();
            Date lastSendMessageDate = userInfoVo.getLastSendMessageDate();
            AssertUtil.instance()
                    //注册手机号与接收验证码的手机号是否一致
                    .isEquals(userInfoVo.getPhoneNumber(),username,ErrorCode.USERNAME_INCONFORMITY)
                     //验证码时效校验
                    .isFalse(DateUtil.getSecondsBetween(date,lastSendMessageDate) > Constant.VERIFYCODE_INVALID,ErrorCode.VERIFYCODE_UNAVAIL)
                    //匹配验证码
                    .isEquals(verifycode,userInfoVo.getVerifycode(),ErrorCode.VERIFYCODE_INCONFORMITY);
        }
        loginInfoMapper.insert(loginInfo);


        Account account = new Account();
        account.setId(loginInfo.getId());
        account.setTradePassword(loginInfo.getPassword());
        //保存用户的基本信息
        accountService.save(account);
        //保存用户的账户信息
        UserInfo userInfo = new UserInfo();
        userInfo.setId(loginInfo.getId());
        userInfo.setPhoneNumber(loginInfo.getUsername());
        userInfoService.save(userInfo);

        //调用第三方接口同步账户
        callInterfaceService.createAccount(username);

        //创建体验金账户
        //发放初始体验金
        ExpAccount expaccount = new ExpAccount();
        expaccount.setId(loginInfo.getId());
        expaccountService.save(expaccount);
        //创建体验金发放记录
        String note = "注册账户,"+loginInfo.getUsername()+"收到系统发放的体验金";
        expAccountGrantRecordService.saveExperienceRecord(expaccount,Constant.EXPERIENCE_THE_INITIAL_AMOUNT_OF_GOLD,note,Constant.INITIAL_EXPERIENCE,new IExpAccountService.LastTime(Constant.EXP_REPAYMENT_MONTH,IExpAccountService.LastTimeUnit.Month));
    }

    @Override
    public boolean existUsername(String username) {
            return  loginInfoMapper.selectByUsername(username) > 0;
    }

    @Override
    public void login(LoginInfo loginInfo, int userType) {
        LoginInfo temp;
        if(userType == LoginInfo.TYPE_WEBSITE){
            AssertUtil.instance()
                    .isMobile(loginInfo.getUsername(),ErrorCode.USERNAME_FORMAT_ERROR)
                    .isLength(loginInfo.getPassword().length(),Constant.PASSWORD_MIN_LENGTH,Constant.PASSWORD_MAX_LENGTH, ErrorCode.PASSWORD_LENGTH_ERROR);
            loginInfo.setPassword(MD5.encode(loginInfo.getPassword() + loginInfo.getUsername()));
             temp = loginInfoMapper.checkUsernameAndPassword(loginInfo);
            AssertUtil.instance().isNotNull(temp,ErrorCode.USERNAME_AND_PASSWORD_INCONFORMITY)
                    .isFalse(temp.getState() == LoginInfo.STATE_LOCK,ErrorCode.ACCOUNT_LOCK);
        }else {
            AssertUtil.instance().isNotNull(loginInfo.getUsername(),ErrorCode.USERNAME_ISNULL)
                    .isLength(loginInfo.getPassword().length(),Constant.PASSWORD_MIN_LENGTH,Constant.PASSWORD_MAX_LENGTH, ErrorCode.PASSWORD_LENGTH_ERROR);
            loginInfo.setPassword(MD5.encode(loginInfo.getPassword() + loginInfo.getUsername()));
            temp = loginInfoMapper.checkUsernameAndPassword(loginInfo);
            AssertUtil.instance().isNotNull(temp,ErrorCode.USERNAME_AND_PASSWORD_INCONFORMITY)
                    .isFalse(temp.getState() == LoginInfo.STATE_LOCK,ErrorCode.ACCOUNT_LOCK);
        }
        UserContext.setLoginInfo(temp);
    }

    @Override
    public List<LoginInfo> listAll() {
        return loginInfoMapper.selectAll();
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        if (loginInfoMapper.selectByUsername(Constant.MGR_USERNAME) == 0) {
            LoginInfo loginInfo = new LoginInfo();
            loginInfo.setUsername(Constant.MGR_USERNAME);
            loginInfo.setPassword(MD5.encode(Constant.MGR_PASSWORD+Constant.MGR_USERNAME));
            loginInfo.setUserType(LoginInfo.TYPE_MGRSITE);
            loginInfoMapper.insert(loginInfo);
        }
    }
}
